﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using Newtonsoft.Json;

namespace RDJTProtocolServer
{
    /**
     * Handler for Requests
     */
    class Rdjtp
    {
        public RdjtpRequest Request { get; private set; }
        public RdjtpResponse Response { get; private set; }

        // Accepted methods of the Server.
        private readonly List<string> _acceptedMethods = new List<string>(){ "create", "read", "update", "delete", "echo" };

        private string _clientMessage;

        public Rdjtp(string message)
        {
            _clientMessage = message;
        }

        public bool ValidateRequest()
        {
            var problemsDetected = new List<string>();

            try
            {
                var request = JsonConvert.DeserializeObject<RdjtpRequest>(_clientMessage);
                Request = request;
            }
            catch (JsonReaderException exception)
            {
                problemsDetected.Add("invalid JSON");
                switch(exception.Path)
                {
                    case "date":
                        problemsDetected.Add("illegal date");
                        break;
                }
                Response = new RdjtpResponse(RdjtpStatus.Error);
                Response.Status = String.Join(", ", problemsDetected);
                return false;
            }

            Response = new RdjtpResponse();

            Response.Status = RdjtpStatus.GetText(RdjtpStatus.BadRequest);

            if (Request.Method == null)
            {
                problemsDetected.Add("missing method");
            }

            // Checking for supported methods.
            if (!_acceptedMethods.Contains(Request.Method))
            {
                problemsDetected.Add("illegal method");
            }
            if (Request.Path == null) problemsDetected.Add("missing resource");
            if (Request.Date == 0) problemsDetected.Add("missing date");
            if (Request.Date < 0 || Request.Date > DateTimeOffset.Now.ToUnixTimeSeconds())
            {
                problemsDetected.Add("illegal date");
            }

            Console.WriteLine("BODY:" + Request.Body);
            if (Request.Method == "create"
                || Request.Method == "update"
                || Request.Method == "echo")
            {
                if (Request.Body == null)
                {
                    problemsDetected.Add("missing body");
                }
                else if (Request.Body != null && Request.Method.Equals("echo"))
                {
                    Response.Status = RdjtpStatus.GetText(RdjtpStatus.Ok);
                    return true;
                }
                else {
                    try{
                        JsonConvert.DeserializeObject<Category>(Request.Body);
                    }
                    catch(Exception e)
                    {
                        Console.WriteLine("ParseError!" + e.ToString());
                        problemsDetected.Add("illegal body");
                    }
                }
            }

            // Concatenating all the messages for the client.
            Response.Status = String.Join(", ", problemsDetected);

            Console.WriteLine("Status: " + Response.Status);

            if (Response.Status.Length > 0)
                return false;
            else {
                Response = new RdjtpResponse(RdjtpStatus.Ok);
                return true;
            }
        }
    }
}
